package com.cd.university.common.obs;

import com.cd.university.common.UniversityConstants;
import com.obs.services.ObsClient;
import com.obs.services.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 华为的OBS工具类
 * 包含基本的操作如文件的上传以及下载
 * @author 陈栋
 * @create 2021/10/13 13:53
 */
@Component
public class ObsUtils {

    @Autowired
    private ObsClient obsClient;

    /**
     * 上传文件，multipartFile就是你要的文件,
     * objectKey就是文件名，如果桶中有文件夹的话，如往test文件上传test.txt文件，那么objectKey就是test/test.txt
     * @param multipartFile 文件流
     * @param objectKey 文件名
     * @param folderName 文件夹名称
     * @return 是否上传载成功
     */
    public boolean uploadFile(MultipartFile multipartFile,
                           String objectKey,
                           String folderName){
        try {
            InputStream inputStream = multipartFile.getInputStream();

            String filePath = getFilePath(folderName, objectKey);
            PutObjectResult putObject = obsClient.putObject(UniversityConstants.OBS_BUCKET_NAME, filePath, inputStream);

            inputStream.close();
//            obsClient.close();
            return true;
        }catch (IOException e) {
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 上传文件，File就是你要的文件,
     * objectKey就是文件名，如果桶中有文件夹的话，如往test文件上传test.txt文件，那么objectKey就是test/test.txt
     * @param file 文件流
     * @param objectKey 文件名
     * @param folderName 文件夹名称
     * @return 返回文件的url
     */
    public String uploadFile(File file,
                              String objectKey,
                              String folderName) {
        try {
            InputStream inputStream = new FileInputStream(file);
            String filePath = getFilePath(folderName, objectKey);
            PutObjectResult putObject = obsClient.putObject(UniversityConstants.OBS_BUCKET_NAME, filePath, inputStream);

            inputStream.close();
            return getFileUrl(objectKey, folderName);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 删除文件
     * @param objectKey 文件对象名
     * @param folderName 文件夹名
     * @return 是否删除载成功
     */
    public boolean deleteFile( String objectKey, String folderName){
        DeleteObjectResult result = obsClient.deleteObject(UniversityConstants.OBS_BUCKET_NAME, getFilePath(folderName, objectKey));
        return true;
    }

    /**
     * 文件下载，下载的文件直接写会到响应中
     * @param objectKey 文件对象名
     * @param folderName 文件夹名
     * @param response 响应
     * @return 是否下载成功
     */
    public boolean downloadFile(String objectKey, String folderName, HttpServletResponse response) {

        response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        // 下载文件能正常显示中文
        String fileName = null;
        try {
            fileName = new String(objectKey.getBytes("UTF-8"),"ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return false;
        }

//        try {
//            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName,"UTF-8"));
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        }

        // 展示用时间戳当文件名
        int indexOf = objectKey.indexOf(".");
        response.setHeader("Content-Disposition", "attachment;filename=" + (System.currentTimeMillis() + objectKey.substring(indexOf,objectKey.length())));

        if (obsClient==null) {
            obsClient = new ObsConfig().getObsClient();
        }
        ObsObject obsObject = obsClient.getObject(UniversityConstants.OBS_BUCKET_NAME, getFilePath(folderName,objectKey));

        // 记录此次下载是否成功
        boolean flag = false;

        // 读取对象内容
        InputStream inputStream = obsObject.getObjectContent();
        byte[] buffer = new byte[1024];
        BufferedInputStream bis = null;

        try {
            bis = new BufferedInputStream(inputStream);
            ServletOutputStream outputStream = response.getOutputStream();

            int i = bis.read(buffer);
            while (i != -1) {
                outputStream.write(buffer, 0, i);
                i = bis.read(buffer);
            }

            // 关闭流
            outputStream.close();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bis !=null) {
                try {
                    bis.close();
                    flag = true;
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    if (!flag) {
                        return false;
                    }
                }
            }
//            try {
//                obsClient.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }finally {
//                if (!flag) {
//                    return false;
//                }
//            }
        }
        return flag;
    }

    /**
     * 获取文件的url地址
     * @param objectKey 文件名
     * @param folderName 文件夹的名字
     * @return 文件的url地址
     */
    public String getFileUrl(String objectKey, String folderName) {
        TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, UniversityConstants.EXPIRE_SECONDS_FILE_URL);
        request.setBucketName(UniversityConstants.OBS_BUCKET_NAME);
        request.setObjectKey(getFilePath(folderName, objectKey));

        TemporarySignatureResponse response = obsClient.createTemporarySignature(request);

        System.out.println("Getting object using temporary signature url:");
        System.out.println("\t" + response.getSignedUrl());
        return response.getSignedUrl();
    }

    /**
     * 或单位一个文件下的所有的文件对象
     * @param folderName 文件夹名称
     * @return 文件夹下的所有文件
     */
    public List<String> getFolderAllFile(String folderName) {
        ListObjectsRequest request = new ListObjectsRequest(UniversityConstants.OBS_BUCKET_NAME);
        // 设置列举带有prefix前缀的100个对象
        request.setPrefix(folderName + "/");
        ObjectListing result = obsClient.listObjects(request);

        ArrayList<String> fileList = new ArrayList<>();

        for(ObsObject obsObject : result.getObjects()){
            fileList.add(obsObject.getObjectKey().substring(folderName.length()+1,obsObject.getObjectKey().length()));
            System.out.println("\t" + obsObject.getObjectKey());
            System.out.println("\t" + obsObject.getOwner());
        }
        return fileList;
    }



    /**
     * 将文件夹名称以及文件名称拼接在一起
     * @param folderName 文件夹名称
     * @param objectKey 文件对象名
     * @return 文件夹/文件对象名
     */
    private String getFilePath(String folderName, String objectKey) {
        return folderName + "/" + objectKey;
    }

}
